#pragma once
#include <iostream>
#include <string>
#include <memory>
#include <jsoncpp/json/json.h>

//设计一下协议的报头和报文的完整格式
// "len"\r\n"{json}"\r\n -- 完整的报文

static const std::string sep = "\r\n";

//添加报头
std::string Encode(const std::string& jsonstr)
{
    int len = jsonstr.size();
    std::string lenstr = std::to_string(len);
    return lenstr + sep + jsonstr + sep;
}
// "len"\r\n"{json}"\r\n
// "len"\r\n"{j
// "len"\r\n"{json}"\r\n// "len"\r\n"{js
// "len"\r\n"{json}"\r\n// "len"\r\n"{json}"\r\n
// "len"\r\n"{json}"\r\n// "len"\r\n"{json}"\r\n// "len"\r\n"{json}"\r\n// "len"\r\n"{json}"\r\

std::string Decode(std::string& packagestream)
{
    auto pos = packagestream.find(sep);
    if(pos == std::string::npos) return std::string();
    std::string lenstr = packagestream.substr(0, pos);
    int len = std::stoi(lenstr);
    //计算一个完整的报文应该是多长
    int total = lenstr.size() + len + 2 * sep.size(); 
    if(packagestream.size() < total) return std::string();
    std::string jsonstr = packagestream.substr(pos+sep.size(), len);
    packagestream.erase(0, total);//这就是Decode参数不能带const的原因，当提取完一个报文之后，要删掉
    return jsonstr;
}

// struct request req = {10, 20, '+'}
class Request
{
public:
    Request()
    {

    }
    Request(int x, int y, char oper):_x(x),_y(y),_oper(oper)
    {
        
    }
    bool Serialize(std::string* out)
    {
        Json::Value root;
        root["x"] = _x;
        root["y"] = _y;
        root["oper"] = _oper;

        Json::FastWriter writer;
        std::string s = writer.write(root); // 把结构化的字段root转换为字符串
        *out = s;
        return true;
    }
    bool Deserialize(const std::string& in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(in, root);

        _x = root["x"].asInt();
        _y = root["y"].asInt();
        _oper = root["oper"].asInt();
        return true;
    }
    void Print()
    {
        std::cout << _x << std::endl;
        std::cout << _y << std::endl;
        std::cout << _oper << std::endl;
    }
    int X()
    {
        return _x;
    }
    int Y()
    {
        return _y;
    }
    char Oper()
    {
        return _oper;
    }
    void SetValue(int x, int y, char oper)
    {
        _x = x;
        _y = y;
        _oper = oper;
    }
    ~Request()
    {
    }

private:
    int _x;
    int _y;
    char _oper; // + - * / %
};

class Response
{
public:
    Response():_result(0),_code(0),_desc("success")
    {
    }
    bool Serialize(std::string* out)
    {
        Json::Value root;
        root["result"] = _result;
        root["code"] = _code;
        root["desc"] = _desc;

        Json::FastWriter writer;
        std::string s = writer.write(root); // 把结构化的字段root转换为字符串
        *out = s;
        return true;
    }
     bool Deserialize(const std::string& in)
    {
        Json::Value root;
        Json::Reader reader;
        bool res = reader.parse(in, root);
        if(!res) return false;

        _result = root["result"].asInt();
        _code = root["code"].asInt();
        _desc = root["desc"].asString();
        return true;
    }
    void PrintResult()
    {
        std::cout << "result: " << _result << ", code:" << _code << ", desc:" << _desc << std::endl;
    }
    ~Response()
    {
    }

public:
    int _result;
    int _code; // 0:success 1:div zero 2:非法操作
    std::string _desc;
};

class Factory
{
public:
    static std::shared_ptr<Request> BuildRequestDafault()
    {
        return std::make_shared<Request>();
    }
    static std::shared_ptr<Response> BuildResponseDafault()
    {
        return std::make_shared<Response>();
    }
};